package com.cvte.boe.media.utils;

import android.content.res.Resources;
import android.graphics.Paint;
import android.graphics.Rect;
import android.net.Uri;
import android.util.Log;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.Collator;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * String Utils
 */
public class StringUtils {

    /**
     * is null or its length is 0 or it is made by space
     * <p/>
     * <pre>
     * isBlank(null) = true;
     * isBlank(&quot;&quot;) = true;
     * isBlank(&quot;  &quot;) = true;
     * isBlank(&quot;a&quot;) = false;
     * isBlank(&quot;a &quot;) = false;
     * isBlank(&quot; a&quot;) = false;
     * isBlank(&quot;a b&quot;) = false;
     * </pre>
     *
     * @param str
     * @return if string is null or its size is 0 or it is made by space, return true, else return false.
     */
    public static boolean isBlank(String str) {
        return (str == null || str.trim().length() == 0);
    }

    /**
     * is null or its length is 0
     * <p/>
     * <pre>
     * isEmpty(null) = true;
     * isEmpty(&quot;&quot;) = true;
     * isEmpty(&quot;  &quot;) = false;
     * </pre>
     *
     * @param str
     * @return if string is null or its size is 0, return true, else return false.
     */
    public static boolean isEmpty(String str) {
        return (str == null || str.length() == 0);
    }

    /**
     * compare two string
     *
     * @param actual
     * @param expected
     * @return
     * @see ObjectUtils#isEquals(Object, Object)
     */
    public static boolean isEquals(String actual, String expected) {
        return ObjectUtils.isEquals(actual, expected);
    }

    /**
     * null string to empty string
     * <p/>
     * <pre>
     * nullStrToEmpty(null) = &quot;&quot;;
     * nullStrToEmpty(&quot;&quot;) = &quot;&quot;;
     * nullStrToEmpty(&quot;aa&quot;) = &quot;aa&quot;;
     * </pre>
     *
     * @param str
     * @return
     */
    public static String nullStrToEmpty(String str) {
        return (str == null ? "" : str);
    }

    /**
     * capitalize first letter
     * <p/>
     * <pre>
     * capitalizeFirstLetter(null)     =   null;
     * capitalizeFirstLetter("")       =   "";
     * capitalizeFirstLetter("2ab")    =   "2ab"
     * capitalizeFirstLetter("a")      =   "A"
     * capitalizeFirstLetter("ab")     =   "Ab"
     * capitalizeFirstLetter("Abc")    =   "Abc"
     * </pre>
     *
     * @param str
     * @return
     */
    public static String capitalizeFirstLetter(String str) {
        if (isEmpty(str)) {
            return str;
        }

        char c = str.charAt(0);
        return (!Character.isLetter(c) || Character.isUpperCase(c)) ? str : new StringBuilder(str.length())
                .append(Character.toUpperCase(c)).append(str.substring(1)).toString();
    }

    /**
     * encoded in utf-8
     * <p/>
     * <pre>
     * utf8Encode(null)        =   null
     * utf8Encode("")          =   "";
     * utf8Encode("aa")        =   "aa";
     * utf8Encode("啊啊啊啊")   = "%E5%95%8A%E5%95%8A%E5%95%8A%E5%95%8A";
     * </pre>
     *
     * @param str
     * @return
     * @throws java.io.UnsupportedEncodingException if an error occurs
     */
    public static String utf8Encode(String str) {
        if (!isEmpty(str) && str.getBytes().length != str.length()) {
            try {
                return URLEncoder.encode(str, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException("UnsupportedEncodingException occurred. ", e);
            }
        }
        return str;
    }

    /**
     * encoded in utf-8, if exception, return defultReturn
     *
     * @param str
     * @param defultReturn
     * @return
     */
    public static String utf8Encode(String str, String defultReturn) {
        if (!isEmpty(str) && str.getBytes().length != str.length()) {
            try {
                return URLEncoder.encode(str, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                return defultReturn;
            }
        }
        return str;
    }

    /**
     * get innerHtml from href
     * <p/>
     * <pre>
     * getHrefInnerHtml(null)                                  = ""
     * getHrefInnerHtml("")                                    = ""
     * getHrefInnerHtml("mp3")                                 = "mp3";
     * getHrefInnerHtml("&lt;a innerHtml&lt;/a&gt;")                    = "&lt;a innerHtml&lt;/a&gt;";
     * getHrefInnerHtml("&lt;a&gt;innerHtml&lt;/a&gt;")                    = "innerHtml";
     * getHrefInnerHtml("&lt;a&lt;a&gt;innerHtml&lt;/a&gt;")                    = "innerHtml";
     * getHrefInnerHtml("&lt;a href="baidu.com"&gt;innerHtml&lt;/a&gt;")               = "innerHtml";
     * getHrefInnerHtml("&lt;a href="baidu.com" title="baidu"&gt;innerHtml&lt;/a&gt;") = "innerHtml";
     * getHrefInnerHtml("   &lt;a&gt;innerHtml&lt;/a&gt;  ")                           = "innerHtml";
     * getHrefInnerHtml("&lt;a&gt;innerHtml&lt;/a&gt;&lt;/a&gt;")                      = "innerHtml";
     * getHrefInnerHtml("jack&lt;a&gt;innerHtml&lt;/a&gt;&lt;/a&gt;")                  = "innerHtml";
     * getHrefInnerHtml("&lt;a&gt;innerHtml1&lt;/a&gt;&lt;a&gt;innerHtml2&lt;/a&gt;")        = "innerHtml2";
     * </pre>
     *
     * @param href
     * @return <ul>
     * <li>if href is null, return ""</li>
     * <li>if not match regx, return source</li>
     * <li>return the last string that match regx</li>
     * </ul>
     */
    public static String getHrefInnerHtml(String href) {
        if (isEmpty(href)) {
            return "";
        }

        String hrefReg = ".*<[\\s]*a[\\s]*.*>(.+?)<[\\s]*/a[\\s]*>.*";
        Pattern hrefPattern = Pattern.compile(hrefReg, Pattern.CASE_INSENSITIVE);
        Matcher hrefMatcher = hrefPattern.matcher(href);
        if (hrefMatcher.matches()) {
            return hrefMatcher.group(1);
        }
        return href;
    }

    /**
     * process special char in html
     * <p/>
     * <pre>
     * htmlEscapeCharsToString(null) = null;
     * htmlEscapeCharsToString("") = "";
     * htmlEscapeCharsToString("mp3") = "mp3";
     * htmlEscapeCharsToString("mp3&lt;") = "mp3<";
     * htmlEscapeCharsToString("mp3&gt;") = "mp3\>";
     * htmlEscapeCharsToString("mp3&amp;mp4") = "mp3&mp4";
     * htmlEscapeCharsToString("mp3&quot;mp4") = "mp3\"mp4";
     * htmlEscapeCharsToString("mp3&lt;&gt;&amp;&quot;mp4") = "mp3\<\>&\"mp4";
     * </pre>
     *
     * @param source
     * @return
     */
    public static String htmlEscapeCharsToString(String source) {
        return StringUtils.isEmpty(source) ? source : source.replaceAll("&lt;", "<").replaceAll("&gt;", ">")
                .replaceAll("&amp;", "&").replaceAll("&quot;", "\"");
    }

    /**
     * transform half width char to full width char
     * <p/>
     * <pre>
     * fullWidthToHalfWidth(null) = null;
     * fullWidthToHalfWidth("") = "";
     * fullWidthToHalfWidth(new String(new char[] {12288})) = " ";
     * fullWidthToHalfWidth("！＂＃＄％＆) = "!\"#$%&";
     * </pre>
     *
     * @param s
     * @return
     */
    public static String fullWidthToHalfWidth(String s) {
        if (isEmpty(s)) {
            return s;
        }

        char[] source = s.toCharArray();
        for (int i = 0; i < source.length; i++) {
            if (source[i] == 12288) {
                source[i] = ' ';
                // } else if (source[i] == 12290) {
                // source[i] = '.';
            } else if (source[i] >= 65281 && source[i] <= 65374) {
                source[i] = (char) (source[i] - 65248);
            } else {
                source[i] = source[i];
            }
        }
        return new String(source);
    }

    /**
     * transform full width char to half width char
     * <p/>
     * <pre>
     * halfWidthToFullWidth(null) = null;
     * halfWidthToFullWidth("") = "";
     * halfWidthToFullWidth(" ") = new String(new char[] {12288});
     * halfWidthToFullWidth("!\"#$%&) = "！＂＃＄％＆";
     * </pre>
     *
     * @param s
     * @return
     */
    public static String halfWidthToFullWidth(String s) {
        if (isEmpty(s)) {
            return s;
        }

        char[] source = s.toCharArray();
        for (int i = 0; i < source.length; i++) {
            if (source[i] == ' ') {
                source[i] = (char) 12288;
                // } else if (source[i] == '.') {
                // source[i] = (char)12290;
            } else if (source[i] >= 33 && source[i] <= 126) {
                source[i] = (char) (source[i] + 65248);
            } else {
                source[i] = source[i];
            }
        }
        return new String(source);
    }

    /**
     * check is dropbox uri
     *
     * @param str
     * @return
     */
    public static boolean isDropBoxURL(String str) {
        if (isEmpty(str)) return false;
        if (str.startsWith("http://dl.dropboxusercontent"))
            return true;
        return false;
    }

    /**
     * check is msp uri
     *
     * @param str
     * @return
     */
    public static boolean isMSPURI(String str) {
        if (isEmpty(str)) return false;
        if (str.startsWith("nsp://"))
            return true;
        return false;
    }

    /**
     * check network uri
     *
     * @param str
     * @return true / false
     */
    public static boolean isNetworkURI(String str) {
        if (isEmpty(str))
            return false;
        if ((str.startsWith("http://")) || (str.startsWith("https://")) || (str.startsWith("rtsp://")))
            return true;
        return false;
    }

    /**
     * check is not empty
     *
     * @param str
     * @return true / false
     */
    public static boolean isNotEmpty(String str) {
        return !isEmpty(str);
    }

    /**
     * check is uri
     *
     * @param str
     * @return true / false
     */
    public static boolean isURI(String str) {
        if (isEmpty(str))
            return false;
        return str.startsWith("content://");
    }

    /**
     * get file name
     *
     * @param str
     * @return
     */
    public static String getFileName(String str) {
        if (isEmpty(str)) {
            return null;
        }
        int start = str.lastIndexOf('/');
        start = start + 0x1;
        int end = str.lastIndexOf('.');
        if (end > start) {
            return str.substring(start, end);
        }
        return null;
    }

    /**
     * get local raw path
     *
     * @param uri
     * @return
     */
    public static String getLocalRawPath(String uri) {
        if (isEmpty(uri)) return null;
        if (!uri.startsWith("file://")) {
            try {
                return Uri.parse(uri).getPath();
            } catch (Exception e) {
            }
        }
        return uri.substring("file://".length());
    }

    public static String getSystemTimeLogText() {
        SimpleDateFormat formatter = new SimpleDateFormat("[yyyy-MM-dd HH:mm:ss.SSS]");
        Date curDate = new Date(System.currentTimeMillis());
        return formatter.format(curDate);
    }

    public static String getSystemTimeText() {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date curDate = new Date(System.currentTimeMillis());
        return formatter.format(curDate);
    }

    public static String getRealText(String text) {
        if (isEmpty(text)) {
            return text;
        }
        ParseEncoding.initParseEncoding();
        try {
            return new String(text.getBytes(), "UTF-8");
        } catch (UnsupportedEncodingException e) {
            return text;
        }
    }

    /**
     * get the number count
     *
     * @param number
     * @return
     */
    public static int getNumCount(int number) {
        if (number < 0) {
            return 0x0;
        }
        if (number <= 0x9) {
            return 0x1;
        }
        int result = 0x1;
        int tempNumber = number;
        while (tempNumber >= 0xa) {
            result = result + 0x1;
            tempNumber = tempNumber / 0xa;
        }
        return result;
    }

    public static String sqlStandardization(String strSql) {
        if (strSql != null) {
            strSql = strSql.replace("\'", "\'\'");
        }
        return strSql;
    }

    public static String formatDeviceDisplayName(String displayName, Resources r, int resid) {
        if (isEmpty(displayName)) {
            displayName = r.getString(resid);
        }
        return displayName;
    }

    public static String formatFolderDisplayName(String displayName, Resources r, int resid) {
        if (isEmpty(displayName)) {
            displayName = r.getString(resid);
        }
        return displayName;
    }

    public static String replaceString(String source, String hi, String hiTarget) {
        if ((isEmpty(source)) || (isEmpty(hiTarget)) || (isEmpty(hi))) {
            return source;
        }
        return source;
    }

    public static String covertToDataFromLong(long timelong, String format) {
        if (isEmpty(format))
            format = "yyyy-MM-dd";
        Date localDate = new Date();
        localDate.setTime(timelong);
        SimpleDateFormat localSimpleDateFormat = new SimpleDateFormat(format);
        try {
            return localSimpleDateFormat.format(localDate);
        } catch (Exception localException) {
        }
        return "";
    }

    public static String getParentFolderName(String filePath) {
        if (isEmpty(filePath)) {
            return null;
        }
        if (filePath.endsWith("/")) {
            filePath = filePath.substring(0x0, filePath.lastIndexOf("/"));
        }
        return filePath.substring((filePath.lastIndexOf("/") + 0x1));
    }

    public static String getFullPinYinLower(String source) {
        if (source == null) {
            return null;
        }
        List<Locale> locales = Arrays.asList(Collator.getAvailableLocales());
        if ((!locales.contains(Locale.CHINA)) && (!locales.contains(Locale.CHINESE)) && (!locales.contains(Locale.SIMPLIFIED_CHINESE))) {
            return source.toLowerCase();
        }
        ArrayList<HanziToPinyin.Token> tokens = HanziToPinyin.getInstance().get(source);
        if ((tokens == null) || (tokens.size() == 0)) {
            return source.toLowerCase();
        }
        StringBuffer result = new StringBuffer();
        for (HanziToPinyin.Token token : tokens) {
            if (token.type == 0x2) {
                result.append(token.target);
            }
            result.append(token.source);
        }
        return result.toString().toLowerCase();
    }

    public static String filterNullData(String data) {
        data = data == null ? "" : data;
        return data;
    }

    public static int getTextLengthOfPix(String text, Paint paint, float textSize) {
        int lengthOfPix = 0x0;
        Rect rc = new Rect();
        if ((paint != null) && (text != null)) {
            paint.setTextSize(textSize);
            paint.getTextBounds(text, 0x0, text.length(), rc);
            lengthOfPix = rc.width();
        }
        return lengthOfPix;
    }

    public static String getThumbFilePath(String path) {
        String[] pathArr = path.split(File.separator);
        if (pathArr.length > 8) {
            StringBuffer buffer = new StringBuffer();
            buffer.append(pathArr[0]).append(File.separator);
            buffer.append(pathArr[1]).append(File.separator);
            buffer.append("...").append(File.separator);
            buffer.append(pathArr[pathArr.length - 2]).append(File.separator);
            buffer.append(pathArr[pathArr.length - 1]);
            return buffer.toString();
        }
        return path;
    }

    public static String transformFileMountPathToDevNamePath(String fileMountPath,String mountName,String devName){
        String tmpFileMountPath = formatMountPointWithoutSeparator(fileMountPath);
        String tmpMountName = formatMountPointWithoutSeparator(mountName);
        String tmpDevName = formatMountPointWithoutSeparator(devName);
        return tmpFileMountPath.replaceFirst(tmpMountName,tmpDevName);
    }

    public static String formatMountPointWithSeparator(String mountPoint){
        if (mountPoint != null && mountPoint.startsWith("file://")) {
            mountPoint = mountPoint.substring("file://".length());
        }
        if (!mountPoint.endsWith(File.separator)) {
            mountPoint = mountPoint.concat(File.separator);
        }
        return mountPoint;
    }
    public static String formatMountPointWithoutSeparator(String mountPoint){
        if (mountPoint != null && mountPoint.startsWith("file://")) {
            mountPoint = mountPoint.substring("file://".length());
        }
        if (mountPoint.endsWith(File.separator)) {
            mountPoint = mountPoint.substring(0, mountPoint.length() - 1);
        }
        return mountPoint;
    }

    public static String formatMediaTimeToString(int mills){
        String time = "";
        mills /= 1000;
        int minute = mills / 60;
        int hour = minute / 60;
        int second = mills % 60;
        minute %= 60;
        try {
            time = String.format(Locale.US, "%02d:%02d:%02d", hour, minute, second);
        } catch (Exception e) {
            time = String.format(Locale.US, "%02d:%02d:%02d", 0, 0, 0);
        }
        return time;
    }
    public static String formatMediaTimeSECAndMINToString(int mills){
        String time = "";
        mills /= 1000;
        int minute = mills / 60;
        int hour = minute / 60;
        int second = mills % 60;
        minute %= 60;
        try {
            time = String.format(Locale.US, "%02d:%02d", minute, second);
        } catch (Exception e) {
            time = String.format(Locale.US, "%02d:%02d", 0, 0);
        }
        return time;
    }
}
